11. Exercise: Refactor onCreateViewHolder
L7 17 ViewHolders Refactor SC PART 2
Now it’s your turn to complete this exercise yourself.
In this exercise, we’ll continue the refactor we started in the prior lesson by encapsulating the logic for creating the ViewHolder into a method called from(), which we’ll then place into a companion object in the ViewHolder class.
Encapsulate the logic for creating the
ViewHolder.Select the code in onCreateViewHolder() and, using the same process as above, refactor it into a
publicmethod calledfrom.Watch the video to see how to use Android Studio tools to do most of this refactor for you.
Move the
fromcode into acompanion object.Click option-enter on the
frommethod, and selectMove to companion object. Then move the resultingcompanion objectinto theViewHolderclass.
Change the
ViewHolderclass declaration to be aprivate constructor:
class ViewHolder private constructor(itemView: View)
Finally, change the return statement in onBindViewHolder to
return ViewHolder.from(parent).Your refactored SleepNightAdapter should now look like this:
class SleepNightAdapter : RecyclerView.Adapter<SleepNightAdapter.ViewHolder>() {
}var data = listOf<SleepNight>() set(value) { field = value notifyDataSetChanged() } override fun getItemCount() = data.size override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = data[position] holder.bind(item) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder.from(parent) } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){ val sleepLength: TextView = itemView.findViewById(R.id.sleep_length) val quality: TextView = itemView.findViewById(R.id.quality_string) val qualityImage: ImageView = itemView.findViewById(R.id.quality_image) fun bind(item: SleepNight) { val res = itemView.context.resources sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res) quality.text = convertNumericQualityToString(item.sleepQuality, res) qualityImage.setImageResource(when (item.sleepQuality) { 0 -> R.drawable.ic_sleep_0 1 -> R.drawable.ic_sleep_1 2 -> R.drawable.ic_sleep_2 3 -> R.drawable.ic_sleep_3 4 -> R.drawable.ic_sleep_4 5 -> R.drawable.ic_sleep_5 else -> R.drawable.ic_sleep_active }) } companion object { fun from(parent: ViewGroup): ViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val view = layoutInflater .inflate(R.layout.list_item_sleep_night, parent, false) return ViewHolder(view) } } }Run the app and verify that it runs exactly as it did before the refactor.
Wow, that was a lot of steps! And the app didn’t change at all! But by using encapsulation to achieve separation of concerns, you’ve made your code much more readable, and easier to maintain.
If you want to start at this step, you can download this exercise from: Step.06-Exercise-Refactor-onCreateViewHolder.
You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.
Once you’re done, you can check your solution against the solution we’ve provided here: Step.06-Solution-Refactor-onCreateViewHolder, or using this git diff.
Task Description:
Complete these steps to refactor onCreateViewHolder().
Task Feedback:
Great job! Your encapsulated ViewHolder is so much simpler!